﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace Pigeon.Utility
{
    public delegate void ThreadCallback(object obj);
    public delegate void ThreadControl();
    public class vThreadPool
    {
        protected Hashtable m_Pool;
        protected Queue<string> m_Queue;
        protected ThreadControl m_control;
        public ThreadControl ControlCallback
        {
            set { m_control = value; }
            get { return m_control; }
        }
        protected long iMaxThreadNum;
        public long MaxThreadNum
        {
            get
            {
                return Interlocked.Read(ref iMaxThreadNum);
            }
        }
        //private long iQueueSize;
        protected long iRunningThreadNum;
        public long RunningThreadNum
        {
            get { return Interlocked.Read(ref iRunningThreadNum); }
        }
        public long ThreadCount { get; set; }
        private long m_Queued;
        public long Queued { get { return Interlocked.Read(ref m_Queued); } }
        public vThreadPool(int MaxThread)
        {
            iMaxThreadNum = MaxThread;
            iRunningThreadNum = 0;
            m_Queued = 0;
            m_Pool = new Hashtable(MaxThread);
            m_Queue = new Queue<string>();
        }
        public void QueueWorkItem(ThreadCallback callback, object obj)
        {
            Thread thread = new Thread(delegate()
                {
                    if (m_control != null) m_control();
                    callback(obj); //这里是实际执行的函数        
                    m_Pool.Remove(Thread.CurrentThread.Name); //将当前线程移出线程池   
                    Interlocked.Decrement(ref iRunningThreadNum); //运行线程数递减   
                    ReleaseQueue(); //释放等待队列中的线程        
                });

            thread.SetApartmentState(ApartmentState.STA);
            string threadGuid = Guid.NewGuid().ToString();
            thread.Name = threadGuid; //保证线程命名唯一     
            m_Pool.Add(threadGuid, thread);
            ThreadCount++;

            //Console.WriteLine(string.Format("R:{0},M:{1}",
            //    Interlocked.Read(ref iRunningThreadNum),
            //    Interlocked.Read(ref iMaxThreadNum)
            //    ));

            if (Interlocked.Read(ref iRunningThreadNum) < Interlocked.Read(ref iMaxThreadNum))
            {
                //Console.WriteLine("启动线程1 _" + ThreadCount);
                thread.Start();
                iRunningThreadNum++;
                //thread.Join();
            }
            else
            {
                m_Queue.Enqueue(thread.Name);
                Interlocked.Increment(ref m_Queued);
            }
        }
        private void ReleaseQueue() //如果等待队列中有线程存在则释放一个，并做减计数       
        {
            try
            {
                if (Interlocked.Read(ref m_Queued) > 0)
                {
                    string threadname = "";
                    lock (m_Queue)
                    {
                        threadname = m_Queue.Dequeue();
                        Interlocked.Decrement(ref m_Queued);
                    }
                    Thread t = m_Pool[threadname] as Thread;
                    //Console.WriteLine("启动线程2");
                    t.Start();
                    iRunningThreadNum++;
                }
            }
            catch (Exception ex)
            {

            }
        }

    }
}